<template>
    <view class="voice-text-container">
        <!-- Switch button between text and voice input -->
        <view class="switch-btn" @tap="handleSwitchTap">
            <uni-icons :type="isVoiceMode ? 'chat' : 'mic'" size="24"
                :class="props.loading ? 'icon-disabled' : ''"></uni-icons>
        </view>

        <!-- Text input mode -->
        <input v-if="!isVoiceMode" class="text-input" type="text" confirm-type="send" :value="inputValue"
            @input="onInput" @confirm="onConfirm" placeholder="请输入消息" :disabled="props.loading"
            :class="{ 'input-loading': props.loading }" />

        <!-- Voice input mode -->
        <view v-else class="voice-btn" :class="{ 'recording': isRecording, 'btn-loading': props.loading }"
            @touchstart="handleTouchStart" @touchend="handleTouchEnd" @touchcancel="handleTouchCancel">
            <view v-if="props.loading" class="loading-spinner"></view>
            <text v-else>{{ isRecording ? '松开 结束' : '按住 说话' }}</text>
        </view>

        <!-- Recording indicator -->
        <view class="recording-indicator" v-if="isRecording">
            <view class="recording-wave">
                <view class="wave" v-for="(item, index) in waveHeight" :key="index" :style="{ height: item + 'rpx' }">
                </view>
            </view>
            <text class="recording-text">正在录音...</text>
            <text class="recognition-result" v-if="realtimeResult">{{ realtimeResult }}</text>
        </view>
    </view>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount } from 'vue';
import uniIcons from '@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue';

// Props
const props = defineProps({
    modelValue: {
        type: String,
        default: ''
    },
    loading: {
        type: Boolean,
        default: false
    }
});

// Emits
const emit = defineEmits(['update:modelValue', 'send']);

// Reactive state
const isVoiceMode = ref(false);
const isRecording = ref(false);
const inputValue = ref('');
const recorderManager = ref(null);
const voicePlugin = ref(null);
const voiceManager = ref(null);
const waveHeight = ref([5, 10, 15, 20, 15, 10, 5]);
const waveTimer = ref(null);
const realtimeResult = ref(''); // Add real-time recognition result state

// Watch for prop changes
watch(() => props.modelValue, (newVal) => {
    inputValue.value = newVal;
});

// Initialize on component mount
onMounted(() => {
    inputValue.value = props.modelValue;

    // Initialize voice plugin and manager
    initVoicePlugin();
});

// Clean up on component unmount
onBeforeUnmount(() => {
    stopWaveAnimation();
});

// Methods
const initVoicePlugin = () => {
    try {
        // Initialize plugin
        voicePlugin.value = requirePlugin("QCloudAIVoice");
        // "qcvoiceSecretId":"AKIDbN4yIE0_bBA2z3KMujpBd2aliaRLTJOmndr-ycfNBihmb2pHEw1Ee0XN4LFjfI98","qcvoiceSecretKey":"+eVDJBwACsiTKpke90BggDBPoQNMArPePl3Int9fMmM=","qcvoiceAppId":"1323702999"
        // Set QCloud credentials
        voicePlugin.value.setQCloudSecret(
            1255813871,
            "AKIDDGByeBZu3nKlDXkpiVQSPEqIdDl7IZuR",
            "lQwUt9NOBoEdwHWo6ILJNNSPF9vdAZ3R",
            true
        );

        // Get recognition manager
        voiceManager.value = voicePlugin.value.getRecordRecognitionManager();

        // Set up event listeners
        setupVoiceManagerListeners();

    } catch (e) {
        console.error('语音插件初始化失败', e);
        // uni.showToast({
        //     title: '语音插件初始化失败',
        //     icon: 'none'
        // });
    }
};

const setupVoiceManagerListeners = () => {
    if (!voiceManager.value) return;

    // Start event
    voiceManager.value.onStart((res) => {
        console.log('recorder start', res.msg);
        isRecording.value = true;
        realtimeResult.value = ''; // Reset result when starting new recording
    });

    // Stop event
    voiceManager.value.onStop((res) => {
        console.log('recorder stop', res.tempFilePath);
        isRecording.value = false;
        stopWaveAnimation();
        // When recording stops, if we have a result, use onConfirm to handle it consistently
        if (realtimeResult.value) {
            inputValue.value = realtimeResult.value;
            onConfirm({
                detail: { value: realtimeResult.value }
            });
        }
    });

    // Error event
    voiceManager.value.onError((res) => {
        console.error('recorder error', res.errMsg);
        isRecording.value = false;
        stopWaveAnimation();
        realtimeResult.value = ''; // Clear result on error
        uni.showToast({
            title: '录音失败',
            icon: 'none'
        });
    });

    // Recognition event
    voiceManager.value.onRecognize((res) => {
        console.log('recorder recognize', res);
        if (res.result || res.resList) {
            console.log("识别结果", res.result);
            inputValue.value = res.result;
            realtimeResult.value = res.result; // Update real-time result
            emit('update:modelValue', inputValue.value);
        } else if (res.errMsg) {
            console.error("recognize error", res.errMsg);
        }
    });
};

const handleSwitchTap = () => {
    if (!props.loading) {
        switchInputMode();
    }
};

const switchInputMode = () => {
    isVoiceMode.value = !isVoiceMode.value;
};

const onInput = (e) => {
    inputValue.value = e.detail.value;
    emit('update:modelValue', inputValue.value);
};

const onConfirm = (e) => {
    emit('send', inputValue.value);
    inputValue.value = '';
    emit('update:modelValue', '');
    realtimeResult.value = ''; // Clear realtime result as well
};

const startRecording = (e) => {
    if (!voiceManager.value) {
        uni.showToast({
            title: '语音识别未初始化',
            icon: 'none'
        });
        return;
    }

    // Start wave animation
    startWaveAnimation();

    // Start recognition
    voiceManager.value.start({
        duration: 60000,
        engine_model_type: "16k_0"
        // Optional parameters:
        // filter_dirty: 0,
        // filter_modal: 0,
        // filter_punc: 0,
        // convert_num_mode: 0,
        // needvad: 1
    });

    // Prevent event propagation
    e.stopPropagation();
};

const stopRecording = (e) => {
    if (!isRecording.value || !voiceManager.value) return;

    voiceManager.value.stop();

    e.stopPropagation();
};

const cancelRecording = (e) => {
    if (!voiceManager.value) return;

    voiceManager.value.stop();
    realtimeResult.value = ''; // Clear result when cancelling

    uni.showToast({
        title: '已取消',
        icon: 'none'
    });

    e.stopPropagation();
};

const startWaveAnimation = () => {
    waveTimer.value = setInterval(() => {
        // Generate random wave heights
        waveHeight.value = waveHeight.value.map(() => {
            return Math.floor(Math.random() * 20) + 5;
        });
    }, 300);
};

const stopWaveAnimation = () => {
    if (waveTimer.value) {
        clearInterval(waveTimer.value);
        waveTimer.value = null;
    }
};

// Methods for touch events
const handleTouchStart = (e) => {
    if (!props.loading) {
        startRecording(e);
    }
};

const handleTouchEnd = (e) => {
    if (!props.loading) {
        stopRecording(e);
    }
};

const handleTouchCancel = (e) => {
    if (!props.loading) {
        cancelRecording(e);
    }
};
</script>

<style>
.voice-text-container {
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 20rpx;
    background-color: #f5f5f5;
    border-radius: 10rpx;
    position: relative;
}

.switch-btn {
    width: 70rpx;
    height: 70rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 20rpx;
}

.text-input {
    flex: 1;
    height: 70rpx;
    background-color: #fff;
    border-radius: 8rpx;
    padding: 0 20rpx;
    font-size: 28rpx;
}

.voice-btn {
    flex: 1;
    height: 70rpx;
    background-color: #fff;
    border-radius: 8rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 28rpx;
    color: #666;
}

.voice-btn.recording {
    background-color: #e6e6e6;
}

.recording-indicator {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 300rpx;
    height: 300rpx;
    background-color: rgba(0, 0, 0, 0.6);
    border-radius: 20rpx;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    z-index: 999;
}

.recording-wave {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    height: 100rpx;
    margin-bottom: 30rpx;
}

.wave {
    width: 10rpx;
    background-color: #07c160;
    margin: 0 5rpx;
    border-radius: 10rpx;
    transition: height 0.2s;
}

.recording-text {
    color: #fff;
    font-size: 28rpx;
    margin-bottom: 10rpx;
}

.recognition-result {
    color: #fff;
    font-size: 24rpx;
    max-width: 260rpx;
    text-align: center;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    margin-top: 10rpx;
    word-break: break-all;
}

.input-loading {
    background-color: #f5f5f5;
    color: #999;
}

.btn-loading {
    background-color: #f5f5f5;
    color: #999;
    pointer-events: none;
}

.loading-spinner {
    width: 20rpx;
    height: 20rpx;
    border: 2rpx solid #999;
    border-radius: 50%;
    border-top-color: transparent;
    animation: spin 0.8s linear infinite;
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

.icon-disabled {
    opacity: 0.5;
    pointer-events: none;
}
</style>